package top.yqingyu.trans$client.main;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.yqingyu.qymsg.DataType;
import top.yqingyu.qymsg.MsgTransfer;
import top.yqingyu.qymsg.MsgType;
import top.yqingyu.qymsg.QyMsg;
import top.yqingyu.common.utils.ThreadUtil;
import top.yqingyu.trans$client.sc.thread.DealMsgThread;

import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ThreadPoolExecutor;


/**
 * @author YYJ
 * @version 1.0.0
 * @ClassName top.yqingyu.thread.ClientInteractionThread
 * @Description 服务器主动操作客户端线程
 * @createTime 2022年05月03日 03:05:00
 */
@Slf4j
public class ClientInteractionThread implements Runnable {


    private static final QyMsg NORM_MSG = new QyMsg(MsgType.NORM_MSG, DataType.JSON);
    private static final QyMsg HEART_BEAT = new QyMsg(MsgType.HEART_BEAT, DataType.JSON);
    private static final ThreadPoolExecutor POOL = ThreadUtil.createQyFixedThreadPool(2, "C-s", null);

    private final TransClient client;
    private MsgTransfer transfer;

    private ClientInteractionThread(TransClient client) {
        this.client = client;
    }

    public static void init(TransClient client) {
        ClientInteractionThread th = new ClientInteractionThread(client);
        NORM_MSG.setFrom(client.clientConf.CLIENT_USER_ID);
        HEART_BEAT.setFrom(client.clientConf.CLIENT_USER_ID);
        th.transfer = MsgTransfer.init(32, client.clientConf.BODY_LENGTH_MAX);
        Thread thread = new Thread(th);
        thread.setName("C2S");
        thread.setDaemon(true);
        thread.start();
    }


    @SneakyThrows
    @Override
    public void run() {
        Socket socket = new Socket(client.clientConf.HOST, client.clientConf.PORT2);
        QyMsg acHeader
                = HEART_BEAT.clone();
        acHeader.putMsg(HEART_BEAT);

        transfer.writeQyMsg(socket, acHeader);


        while (client.running.get()) {
            try {
                QyMsg readMsg = transfer.readQyMsg(socket, client.running);
                POOL.execute(new DealMsgThread(readMsg, client, socket, transfer));
            } catch (IOException e) {
                socket = new Socket(client.clientConf.HOST, client.clientConf.PORT2);
                transfer.writeQyMsg(socket, acHeader);
            } catch (Exception e) {
                log.error("异常", e);
            }

            Thread.sleep(client.clientConf.HEART_BEAT_TIME);
        }
    }
}
